package com.sfdk.admin.data.weaponEditor
{
    import com.sfdk.admin.ApplicationData;
    import com.sfdk.admin.data.RectangleEx;
    import com.sfdk.admin.data.spritesheetEditor.TilePiece;
    import com.sfdk.admin.structure.VectorCollection;
    import com.sfdk.data.api.ITreeDataProvider;
    import com.sfdk.events.IOEvent;
    import com.sfdk.graphics.core.BitmapEx;
    import com.sfdk.io.GenericIO;
    import com.sfdk.pools.BitmapExPool;

    import flash.display.BitmapData;
    import flash.events.Event;
    import flash.utils.Dictionary;

    public class WeaponAnimationDefinition extends GenericIO implements ITreeDataProvider
    {
        private var _fullName:String;
        private var _type:String;
        private var _rootType:String;
        private var _name:String;

        public function WeaponAnimationDefinition(currentDirectory:String = null, filePath:String = null) {
            _fullName = filePath;
            if (filePath != null) {
                var pathArray:Array = filePath.split("/");
                _type = pathArray[pathArray.length - 2];
                _rootType = pathArray[1];
                _name = pathArray[pathArray.length - 1];
            }

            super(currentDirectory + filePath, GenericIO.XML_FILE);
        }

        public static const LEFT_DIRECTION:String = "LEFT_DIRECTION";
        public static const TOP_LEFT_DIRECTION:String = "TOP_LEFT_DIRECTION";
        public static const TOP_DIRECTION:String = "TOP_DIRECTION";
        public static const TOP_RIGHT_DIRECTION:String = "TOP_RIGHT_DIRECTION";
        public static const RIGHT_DIRECTION:String = "RIGHT_DIRECTION";
        public static const BOTTOM_RIGHT_DIRECTION:String = "BOTTOM_RIGHT_DIRECTION";
        public static const BOTTOM_DIRECTION:String = "BOTTOM_DIRECTION";
        public static const BOTTOM_LEFT_DIRECTION:String = "BOTTOM_LEFT_DIRECTION";

        private var _tileList:VectorCollection = new VectorCollection(new Vector.<TilePiece>());
        private var _tileById:Dictionary = new Dictionary();
        private var _bitmapExMap:Dictionary = new Dictionary();

        private var _basicWeaponAnimation:Dictionary = new Dictionary();

        private var _definedWeaponAnimation:VectorCollection = new VectorCollection(new Vector.<WeaponPiece>());

        private var _toLoad:int;


        public function get fullName():String {
            return _fullName;
        }


        public function set fullName(value:String):void {
            _fullName = value;
        }

        public function get label():String {
            return _name;
        }

        public function set name(value:String):void {
            _name = value;
        }

        public function get type():String {
            return _type;
        }

        public function get rootType():String {
            return _rootType;
        }

        public function get isImage():Boolean {
            return false;
        }

        public function get imageData():BitmapData {
            return null;
        }

        public function get definedWeaponAnimation():VectorCollection {
            return _definedWeaponAnimation;
        }

        public function get basicWeaponAnimation():Dictionary {
            return _basicWeaponAnimation;
        }

        public function get tileList():VectorCollection {
            return _tileList;
        }

        public function get tileById():Dictionary {
            return _tileById;
        }

        override protected function init():void {
            var fileXML:XML = _fileInfo;
            var sourcesList:XMLList = fileXML.descendants("file");

            _toLoad = 0;
            var source:XML;
            for each(source in sourcesList) {
                var bitmapEx:BitmapEx = BitmapExPool.instance.getFromPool(source.@fileName, ApplicationData.BASE_LOCATION+ApplicationData.RESOURCE_DIRECTORY);
                var tilePiece:TilePiece = new TilePiece();
                tilePiece.fileName = source.@fileName;
                tilePiece.id = source.@id;
                _tileById[tilePiece.id] = tilePiece;
                if (!bitmapEx.isLoaded) {
                    _toLoad++;
                    bitmapEx.addEventListener("bitmapExLoaded", onSourceLoaded);
                    _bitmapExMap[bitmapEx] = tilePiece;
                }
                else {
                    var bitmapData:BitmapData = bitmapEx.getImageData();
                    var sourceRectEx:RectangleEx = new RectangleEx(0, 0, bitmapData.width, bitmapData.height);
                    tilePiece.init(bitmapData, sourceRectEx);
                }
                _tileList.addItem(tilePiece);

            }
        }

        private function onSourceLoaded(e:Event):void {
            _toLoad--;
            var bitmapEx:BitmapEx = e.target as BitmapEx;
            var tilePiece:TilePiece = _bitmapExMap[bitmapEx];
            var bitmapData:BitmapData = bitmapEx.getImageData();
            var sourceRectEx:RectangleEx = new RectangleEx(0, 0, bitmapData.width, bitmapData.height);
            tilePiece.init(bitmapData, sourceRectEx);
            if (_toLoad == 0) {
                onAllSourcesLoaded();
            }
        }

        private function onAllSourcesLoaded():void {
            var fileXML:XML = _fileInfo;
            var weaponList:XMLList = fileXML.descendants("weapon");
            var weapon:XML;
            var tileDefinition:XML;

            var direction:String;
            var tileId:int;
            var horizontalFlip:Boolean;
            var verticalFlip:Boolean;

            var weaponPiece:WeaponPiece;

            for each(weapon in weaponList) {
                direction = weapon.@direction;
                tileDefinition = weapon.descendants('tileDefinition')[0];
                tileId = tileDefinition.@id;
                horizontalFlip = (tileDefinition.@horizontalFlip == "true");
                verticalFlip = (tileDefinition.@verticalFlip == "true");

                weaponPiece = new WeaponPiece();
                weaponPiece.id = tileId;
                weaponPiece.direction = direction;
                weaponPiece.bitmapData = (_tileById[tileId] as TilePiece).bitmapData;
                weaponPiece.sourceRect = (_tileById[tileId] as TilePiece).sourceRect;
                weaponPiece.horizontalFlip = horizontalFlip;
                weaponPiece.verticalFlip = verticalFlip;

                _definedWeaponAnimation.addItem(weaponPiece);
                if (direction != null) {
                    _basicWeaponAnimation[direction] = weaponPiece;
                }
            }
            dispatchEvent(new IOEvent(IOEvent.LOAD_COMPLETE));
        }


        private function getMaxTileID():int {
            var tilePiece:TilePiece;
            var maxID:int = -1;
            for each(tilePiece in _tileList) {
                if (tilePiece.id > maxID)
                    maxID = tilePiece.id;
            }
            return maxID;
        }

        public function addSource(bitmapEx:BitmapEx):void {
            var tilePiece:TilePiece = new TilePiece();
            var bitmapData:BitmapData = bitmapEx.getImageData();
            var sourceRectEx:RectangleEx = new RectangleEx(0, 0, bitmapData.width, bitmapData.height);

            tilePiece.id = getMaxTileID()+1;
            tilePiece.fileName = bitmapEx.fullName;
            tilePiece.init(bitmapData, sourceRectEx);

            _tileById[tilePiece.id] = tilePiece;
            _tileList.addItem(tilePiece);
        }


        public function addWeaponPiece(weaponPiece:WeaponPiece):void {
           _definedWeaponAnimation.addItem(weaponPiece);
        }

        public function removeSources(selectedItems:Vector.<Object>):void {
            for each(var selectedTilePiece : TilePiece in selectedItems)
            {
                var index : int = _tileList.getItemIndex(selectedTilePiece);
                if(index != -1)
                {
                    _tileList.removeItemAt(index);
                    delete _tileById[selectedTilePiece.id];
                    // Let's remove all the weapon Piece associated
                    var toRemove : Vector.<WeaponPiece> = new Vector.<WeaponPiece>();
                    for each(var weaponPiece : WeaponPiece in _definedWeaponAnimation)
                    {
                        if(weaponPiece.id == selectedTilePiece.id)
                        {
                            toRemove.push(weaponPiece);
                        }
                    }
                    for each(weaponPiece in toRemove)
                    {
                        if(weaponPiece.direction != null)
                        {
                            delete _basicWeaponAnimation[weaponPiece.direction];
                        }
                        _definedWeaponAnimation.removeItemAt(_definedWeaponAnimation.getItemIndex(weaponPiece));
                    }
                }
            }
            dispatchEvent(new Event("weaponPieceChanged"));
        }
    }
}